home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / viewkit / VCal / Utils.c++ < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  11.1 KB  |  610 lines

  1. /*
  2.  * Copyright (C) 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. #include <stdio.h>
  18. #include <string.h>
  19. #include <time.h>
  20. #include <sys/time.h>
  21. #include <sys/types.h>
  22. #include "Utils.h"
  23.  
  24. static char *smonth[13]= {
  25.   NULL, "January", "February", "March", "April", "May", "June", "July",
  26.   "August", "September", "October", "November", "December",
  27. };
  28.  
  29. static char *sweek[8]= {
  30.   NULL, "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
  31.   "Saturday",
  32. };
  33.  
  34. int
  35. isWhiteSpace(char ch)
  36. {
  37.   return (ch == ' ' || ch == ',' || ch == '\t');
  38. }
  39.  
  40. static char *
  41. skipWhiteSpace(char *ptr)
  42. {
  43.   while (isWhiteSpace(*ptr)) {
  44.     ptr++;
  45.   }
  46.   return ptr;
  47. }
  48.  
  49. static char *
  50. parseWord(char *ptr, char *str_return)
  51. {
  52.   while (!isWhiteSpace(*ptr) && *ptr != '\0') {
  53.     *str_return = *ptr;
  54.     ptr++;
  55.     str_return++;
  56.   }
  57.   *str_return = '\0';
  58.   return skipWhiteSpace(ptr);
  59. }
  60.  
  61. static char *
  62. parseNumber(char *ptr, int *num_return)
  63. {
  64.   char dummy[256];
  65.  
  66.   if (sscanf(ptr, "%d", num_return) == 1) {
  67.     return parseWord(ptr, dummy);
  68.   } else {
  69.     return NULL;
  70.   }
  71. }
  72.  
  73. /**********************************************************************/
  74.  
  75. void
  76. formatTime(int hour, int min, int clock24, char *str_return)
  77. {
  78.   if (clock24) {
  79.     sprintf(str_return, "%d:", hour);
  80.     if (min < 10) {
  81.       strcat(str_return, "0");
  82.     }
  83.     sprintf(str_return+strlen(str_return), "%d", min);
  84.   } else {
  85.     formatShortTime(hour, min, str_return);
  86.     if (hour >= 12) {
  87.       strcat(str_return, "pm");
  88.     } else {
  89.       strcat(str_return, "am");
  90.     }
  91.   }
  92. }
  93.  
  94. void
  95. formatShortTime(int hour, int min, char *str_return)
  96. {
  97.   if (hour % 12 == 0) {
  98.     sprintf(str_return, "12:");
  99.   } else {
  100.     sprintf(str_return, "%d:", hour % 12);
  101.   }
  102.   if (min < 10) {
  103.     strcat(str_return, "0");
  104.   }
  105.   sprintf(str_return+strlen(str_return), "%d", min);
  106. }
  107.  
  108. void
  109. formatDate(int weekday, int day, int month, int year, char *str_return)
  110. {
  111.   if (weekday && month) {
  112.     if (year) {
  113.       sprintf(str_return, "%s, %s %d, %d", sweek[weekday], smonth[month],
  114.           day, year);
  115.     } else {
  116.       sprintf(str_return, "%s, %s %d", sweek[weekday], smonth[month],
  117.           day);
  118.     }
  119.   } else {
  120.     strcpy(str_return, "");
  121.   }
  122. }
  123.  
  124. void
  125. formatDate(int day, int month, int year, char *str_return)
  126. {
  127.   if (month) {
  128.     if (year) {
  129.       sprintf(str_return, "%s %d, %d", smonth[month], day, year);
  130.     } else {
  131.       sprintf(str_return, "%s %d", smonth[month], day);
  132.     }
  133.   } else {
  134.     strcpy(str_return, "");
  135.   }
  136. }
  137.  
  138. void
  139. formatDate(int month, int year, char *str_return)
  140. {
  141.   if (month) {
  142.     sprintf(str_return, "%s %d", smonth[month], year);
  143.   } else {
  144.     strcpy(str_return, "");
  145.   }
  146. }
  147.  
  148. int
  149. readInt(FILE *fd, int *num)
  150. {
  151.   static char str[MAXSTR];
  152.  
  153.   return (fgets(str, sizeof(str), fd) && (sscanf(str, "%d", num) == 1));
  154. }
  155.  
  156. void
  157. writeInt(FILE *fd, int num, char *annotation)
  158. {
  159.   static char str[20];
  160.   int each;
  161.  
  162.   if (annotation) {
  163.     sprintf(str, "%d", num);
  164.     for (each=strlen(str); each<sizeof(str)-1; each++) {
  165.       str[each] = ' ';
  166.     }
  167.     str[sizeof(str)-1] = '\0';
  168.     fprintf(fd, "%s%s\n", str, annotation);
  169.   } else {
  170.     fprintf(fd, "%d\n", num);
  171.   }
  172. }
  173.  
  174. int
  175. readStr(FILE *fd, char *str_return)
  176. {
  177.   static char str[MAXSTR];
  178.   int len, str_ct, each;
  179.  
  180.   if (!fgets(str, sizeof(str), fd)) {
  181.     return 0;
  182.   } else {
  183.     len = strlen(str);
  184.     if (str[len-1] == '\n') {
  185.       str[len-1] = '\0';
  186.       len--;
  187.     }
  188.     str_ct = 0;
  189.     for (each=0; each<len; each++) {
  190.       if (str[each] == '\\' && each < len-1 && str[each+1] == 'n') {
  191.     str_return[str_ct] = '\n';
  192.     each++;
  193.       } else {
  194.     str_return[str_ct] = str[each];
  195.       }
  196.       str_ct++;
  197.     }
  198.     str_return[str_ct] = '\0';
  199.     return 1;
  200.   }
  201. }
  202.  
  203. void
  204. writeStr(FILE *fd, char *str)
  205. {
  206.   int each, len;
  207.  
  208.   len = strlen(str);
  209.   if (len > MAXSTR/2) {
  210.     len = MAXSTR/2;
  211.   }
  212.   for (each=0; each<len; each++) {
  213.     if (str[each] == '\n') {
  214.       fprintf(fd, "\\n");
  215.     } else {
  216.       fprintf(fd, "%c", str[each]);
  217.     }
  218.   }
  219.   fprintf(fd, "\n");
  220. }
  221.  
  222. int
  223. parseDate(char *str, int *day, int *month, int *year)
  224. {
  225.   char *slash1, *slash2, *ptr, token[256];
  226.   struct tm *now;
  227.   struct timeval t;
  228.  
  229.   gettimeofday(&t, NULL);
  230.   now = localtime(&t.tv_sec);
  231.   if (!strlen(str)) {
  232.     *day = *month = *year = 0;
  233.     return 1;
  234.   } else if (!strcasecmp(str, "today")) {
  235.     *day = now->tm_mday;
  236.     *month = now->tm_mon+1;
  237.     *year = now->tm_year+1900;
  238.     return 1;
  239.   } else if ((slash1 = strchr(str, '/')) &&
  240.          (slash2 = strrchr(str, '/'))) {
  241.     if (slash1 != slash2 &&
  242.     strchr(slash1+1, '/') == slash2) {
  243.       if (sscanf(str, "%d", month) == 1 &&
  244.       sscanf(slash1+1, "%d", day) == 1 &&
  245.       sscanf(slash2+1, "%d", year) == 1) {
  246.     if (*year < 100) {
  247.       *year += 1900;
  248.     }
  249.     return 1;
  250.       }
  251.     } else if (slash1 == slash2) {
  252.       if (sscanf(str, "%d", month) == 1 &&
  253.       sscanf(slash1+1, "%d", day) == 1) {
  254.     *year = now->tm_year+1900;
  255.     return 1;
  256.       }
  257.     }
  258.     return 0;
  259.   } else {
  260.     ptr = skipWhiteSpace(str);
  261.     if (!ptr) {
  262.       return 0;
  263.     }
  264.     ptr = parseWord(ptr, token);
  265.     *month = matchMonthString(token);
  266.     if (!ptr || !(*month)) {
  267.       return 0;
  268.     }
  269.     ptr = parseNumber(ptr, day);
  270.     if (!ptr || *day < 1) {
  271.       return 0;
  272.     }
  273.     if (*ptr == '\0') {
  274.       *year = now->tm_year+1900;
  275.       return 1;
  276.     }
  277.     ptr = parseNumber(ptr, year);
  278.     if (!ptr || *ptr != '\0') {
  279.       return 0;
  280.     }
  281.     if (*year < 100) {
  282.       *year += 1900;
  283.     }
  284.     if (*day > NumberOfDays(*month, *year)) {
  285.       return 0;
  286.     }
  287.     return 1;
  288.   }
  289. }
  290.  
  291. int
  292. parseMonth(char *str, int *month, int *year)
  293. {
  294.   int day;
  295.   char *slash1, *slash2, *ptr, token[256];
  296.   struct tm *now;
  297.   struct timeval t;
  298.  
  299.   gettimeofday(&t, NULL);
  300.   now = localtime(&t.tv_sec);
  301.   if (parseDate(str, &day, month, year)) {
  302.     return 1;
  303.   } else if (!strlen(str)) {
  304.     *month = *year = 0;
  305.     return 1;
  306.   } else if ((slash1 = strchr(str, '/')) &&
  307.          (slash2 = strrchr(str, '/'))) {
  308.     if (slash1 != slash2 &&
  309.     strchr(slash1+1, '/') == slash2) {
  310.       if (sscanf(str, "%d", month) == 1 &&
  311.       sscanf(slash1+1, "%d", &day) == 1 &&
  312.       sscanf(slash2+1, "%d", year) == 1) {
  313.     if (*year < 100) {
  314.       *year += 1900;
  315.     }
  316.     return 1;
  317.       }
  318.     } else if (slash1 == slash2) {
  319.       if (sscanf(str, "%d", month) == 1 &&
  320.       sscanf(slash1+1, "%d", year) == 1) {
  321.     if (*year < 100) {
  322.       *year += 1900;
  323.     }
  324.     return 1;
  325.       }
  326.     }
  327.     return 0;
  328.   } else {
  329.     ptr = skipWhiteSpace(str);
  330.     if (!ptr) {
  331.       return 0;
  332.     }
  333.     ptr = parseWord(ptr, token);
  334.     *month = matchMonthString(token);
  335.     if (!ptr || !(*month)) {
  336.       return 0;
  337.     }
  338.     if (*ptr == '\0') {
  339.       *year = now->tm_year+1900;
  340.       return 1;
  341.     }
  342.     ptr = parseNumber(ptr, year);
  343.     if (!ptr || *ptr != '\0') {
  344.       return 0;
  345.     }
  346.     if (*year < 100) {
  347.       *year += 1900;
  348.     }
  349.     return 1;
  350.   }
  351. }
  352.  
  353. int
  354. compareDates(int day1, int month1, int year1, int day2, int month2, int year2)
  355. {
  356.   if (year1 < year2) {
  357.     return -1;
  358.   } else if (year1 > year2) {
  359.     return 1;
  360.   }
  361.   if (month1 < month2) {
  362.     return -1;
  363.   } else if (month1 > month2) {
  364.     return 1;
  365.   }
  366.   if (day1 < day2) {
  367.     return -1;
  368.   } else if (day1 > day2) {
  369.     return 1;
  370.   }
  371.   return 0;
  372. }
  373.          
  374. int
  375. computeWeekday(int day, int month, int year)
  376. {
  377.   static int lastFirst, lastMonth = 0, lastYear = 0;
  378.  
  379.   if (month != lastMonth || year != lastYear) {
  380.     lastFirst = FirstDay(month, year);
  381.     lastMonth = month;
  382.     lastYear = year;
  383.   }
  384.   return ((day+lastFirst-2) % 7)+1;
  385. }
  386.  
  387. int
  388. computeDayDifference(int day1, int month1, int year1,
  389.              int day2, int month2, int year2)
  390. {
  391.   int diff, m, y, num;
  392.  
  393.   diff = 0;
  394.   num = NumberOfDays(month2, year2);
  395.   if (year1 > year2 || month1 > month2) {
  396.     diff += num-day2;
  397.   } else if (day1 > day2) {
  398.     diff += day1-day2;
  399.   }
  400.   if (year1 > year2) {
  401.     for (m=month2+1; m<=12; m++) {
  402.       diff += NumberOfDays(m, year2);
  403.     }
  404.   } else {
  405.     for (m=month2+1; m<month1; m++) {
  406.       diff += NumberOfDays(m, year2);
  407.     }
  408.   }
  409.   for (y=year2+1; y<year1; y++) {
  410.     if (y % 400 == 0) {
  411.       diff += 366;
  412.     } else if (y % 100 == 0) {
  413.       diff += 365;
  414.     } else if (y % 4 == 0) {
  415.       diff += 366;
  416.     } else {
  417.       diff += 365;
  418.     }
  419.   }
  420.   if (year1 > year2) {
  421.     for (m=1; m<month1; m++) {
  422.       diff += NumberOfDays(m, year1);
  423.     }
  424.   }
  425.   if (year1 > year2 || month1 > month2) {
  426.     diff += day1;
  427.   }
  428.   return diff;
  429. }
  430.  
  431. void
  432. augmentDate(int day, int month, int year, int days, int *d, int *m, int *y)
  433. {
  434.   *d = day;
  435.   *m = month;
  436.   *y = year;
  437.   while (days > NumberOfDays(*m, *y)-*d) {
  438.     days -= NumberOfDays(*m, *y)-*d;
  439.     *d = 0;
  440.     (*m)++;
  441.     if (*m == 12) {
  442.       *m = 0;
  443.       (*y)++;
  444.     }
  445.   }
  446.   (*d) += days;
  447. }
  448.  
  449. void
  450. decrementDate(int day, int month, int year, int days, int *d, int *m, int *y)
  451. {
  452.   *d = day;
  453.   *m = month;
  454.   *y = year;
  455.  
  456.   if (*d > days) {
  457.     *d -= days;
  458.   } else {
  459.     days -= *d;
  460.     if (!*m) {
  461.       *m = 12;
  462.       (*y)--;
  463.     } else {
  464.       (*m)--;
  465.     }
  466.     *d = NumberOfDays(*m, *y)-days;
  467. // Oops, what if days > # days in month????
  468.   }
  469. }
  470.  
  471. int
  472. matchMonthString(char *str)
  473. {
  474.   int each;
  475.  
  476.   for (each=1; each<=12; each++) {
  477.     if (!strcasecmp(str, smonth[each])) {
  478.       return each;
  479.     }
  480.   }
  481. // Now try just the first three letters
  482.   if (strlen(str) == 3) {
  483.     for (each=1; each<=12; each++) {
  484.       if (!strncasecmp(str, smonth[each], 3)) {
  485.     return each;
  486.       }
  487.     }
  488.   }
  489.   return 0;
  490. }
  491.  
  492. char *
  493. monthString(int month)
  494. {
  495.   return smonth[month];
  496. }
  497.  
  498. char *
  499. weekdayString(int day)
  500. {
  501.   return sweek[day];
  502. }
  503.  
  504. /**********************************************************************/
  505.  
  506. //
  507. // Taken from xcalendar source
  508. //
  509.  
  510. static char mon[] = {
  511.   0,
  512.   31, 29, 31, 30,
  513.   31, 30, 31, 31,
  514.   30, 31, 30, 31,
  515. };
  516.  
  517. static int calInit = 0;
  518.  
  519. /*
  520.  *    return day of the week
  521.  *    of jan 1 of given year
  522.  */
  523.  
  524. int
  525. jan1(int yr)
  526. {
  527.   register y, d;
  528.  
  529. /*
  530.  *    normal gregorian calendar
  531.  *    one extra day per four years
  532.  */
  533.  
  534.   y = yr;
  535.   d = 4+y+(y+3)/4;
  536.  
  537. /*
  538.  *    julian calendar
  539.  *    regular gregorian
  540.  *    less three days per 400
  541.  */
  542.  
  543.   if(y > 1800) {
  544.     d -= (y-1701)/100;
  545.     d += (y-1601)/400;
  546.   }
  547.  
  548. /*
  549.  *    great calendar changeover instant
  550.  */
  551.  
  552.   if(y > 1752)
  553.     d += 3;
  554.   
  555.   return(d%7);
  556. }
  557.  
  558. /* should be called first */
  559. int
  560. FirstDay(int m, int y)
  561. {
  562.   register d, i;
  563.   
  564.   calInit = y;
  565.   d = jan1(y);
  566.   mon[2] = 29;
  567.   mon[9] = 30;
  568.   
  569.   switch((jan1(y+1)+7-d)%7) {
  570.     
  571.     /*
  572.      *    non-leap year
  573.      */
  574.   case 1:
  575.     mon[2] = 28;
  576.     break;
  577.     
  578.     /*
  579.      *    1752
  580.      */
  581.   default:
  582.     mon[9] = 19;
  583.     break;
  584.     
  585.     /*
  586.      *    leap year
  587.      */
  588.   case 2:
  589.     ;
  590.   }
  591.   
  592.   for(i=1; i<m; i++)
  593.     d += mon[i];
  594.   d %= 7;
  595.   
  596.   d = d>0 ? d : 7;        /* returns 1-7, not 0-6 */
  597.   
  598.   d = d + 1 - 0; // d = d + 1 - appResources.firstDay;
  599.   return d>0 ? d : 7+d;
  600. }
  601.  
  602. int
  603. NumberOfDays(int m, int y)
  604. {
  605.   if(calInit != y)
  606.     FirstDay(m,y);
  607.   return mon[m];
  608. }
  609.  
  610.